using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;

/// <summary>
/// JAR manifest parser
/// </summary>
public static class ManifestParser
{
    /// <summary>
    /// Parses manifest data
    /// </summary>
    /// <param name="jar">Jar file to parse</param>
    /// <param name="reader">Stream reader</param>
    /// <returns><see cref="JarFile"/> with parsed manifest data</returns>
    public static void ParseManifestAsync(this JarFile jar, StreamReader reader)
    {
        var line =  reader.ReadLine();
        while (line != null)
        {
            if (string.IsNullOrEmpty(line))
            {
                line =  reader.ReadLine();
                continue;
            }
            bool isNeedRead=true;
            var pair = line.Split(':', StringSplitOptions.None);
            if (pair.Length == 2)
            {
                var key = pair[0].Trim().ToLowerInvariant();
                var value = pair[1].Trim();
                jar.Manifest.Datas.Add(key, value);
                switch (key)
                {
                    case "manifest-version":
                        {
                            if (Version.TryParse(value, out var result))
                                jar.Manifest.ManifestVersion = result;
                        }
                        break;

                    case "implementation-vendor":
                        jar.Manifest.ImplementationVendor = value;
                        break;

                    case "implementation-title":
                        jar.Manifest.ImplementationTitle = value;
                        break;

                    case "implementation-version":
                        {
                            var version = value.Replace('_', '.');
                            if (version.Contains('-'))
                                version = version[..version.IndexOf('-')];

                            if (Version.TryParse(version, out var result))
                                jar.Manifest.ImplementationVersion = result;
                        }
                        break;

                    case "specification-vendor":
                        jar.Manifest.SpecificationVendor = value;
                        break;

                    case "created-by":
                        jar.Manifest.CreatedBy = value;
                        break;

                    case "specification-title":
                        jar.Manifest.SpecificationTitle = value;
                        break;

                    case "specification-version":
                        {
                            if (Version.TryParse(value, out var result))
                                jar.Manifest.SpecificationVersion = result;
                        }
                        break;

                    case "main-class":
                        jar.Manifest.MainClass = value;
                        break;

                    case "midlet-name":
                        jar.Manifest.MIDletName = value;
                        break;
                    case "midlet-1":
                    case "0":
                    case "1":
                    case "2":
                    case "3":
                    case "4":
                    case "5":
                    case "6":
                    case "7":
                    case "8":
                        
                        string?[] m = value.Split(',');
                        for (int i = 0; i < m.Length; i++)
                        {
                            m[i] = m[i].Trim();
                        }
                        int index = jar.Manifest.MIDlets.Count;
                        jar.Manifest.MIDlets.Add(m);
                        line = reader.ReadLine();
                        isNeedRead = false;
                        if(!string.IsNullOrEmpty(line))
                        {
                            var pair2 = line.Split(':', StringSplitOptions.None);
                            if (pair2.Length < 2)
                            {
                                isNeedRead = true;
                                line.Trim();
                                if(line[0]==' ')
                                {
                                    line= line.Substring(1, line.Length - 1);
                                }
                                jar.Manifest.MIDlets[index][2] += line;
                            }
                        }
                        break;
                    case "midlet-description":
                       
                        break;
                    case "midlet-version":
                        jar.Manifest.MIDletVersion = value;
                        break;
                    case "midlet-icon":
                        jar.Manifest.MIDletIcon = value;
                        break;
                    default:
                        break;
                }
            }
            if(isNeedRead)
            line = reader.ReadLine();
        }
    }
}

/// <summary>
/// JAR manifest data
/// </summary>
public class ManifestData
{
    public string MIDletName;
    public string MIDletIcon;
    public string MIDletVersion;
    public Dictionary<string, string> Datas = new Dictionary<string, string>();
    /// <summary>
    /// Manifest version
    /// </summary>
    public Version? ManifestVersion { get; set; }

    /// <summary>
    /// Implementation vendor name
    /// </summary>
    public string? ImplementationVendor { get; set; }

    /// <summary>
    /// Implementation title
    /// </summary>
    public string? ImplementationTitle { get; set; }

    /// <summary>
    /// Implementation version
    /// </summary>
    public Version? ImplementationVersion { get; set; }

    /// <summary>
    /// Specification vendor
    /// </summary>
    public string? SpecificationVendor { get; set; }

    /// <summary>
    /// Creator name
    /// </summary>
    public string? CreatedBy { get; set; }

    /// <summary>
    /// Specification title
    /// </summary>
    public string? SpecificationTitle { get; set; }

    /// <summary>
    /// Specification version
    /// </summary>
    public Version? SpecificationVersion { get; set; }

    /// <summary>
    /// Main entry class
    /// </summary>
    public string? MainClass { get; set; }

    public List<string?[]> MIDlets=new List<string?[]>();
}

public class Version
{
    public string version;
    internal static bool TryParse(string value, out Version result)
    {
        result = new Version();
        result.version = value;
        return true;
    }
}
